package cn.itcast.star.graph.core.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.itcast.star.graph.core.pojo.dto.common.Result;
import cn.itcast.star.graph.core.pojo.dto.common.ResultCode;
import cn.itcast.star.graph.core.utils.JWTUtils;
import cn.itcast.star.graph.core.utils.UserUtils;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

/**
 * @author Windows
 */
@Component
public class UserInterceptor implements HandlerInterceptor {
    @Resource
    private JWTUtils jwtUtil;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        try {
            //需要验证授权
            String token = request.getHeader((HttpHeaders.AUTHORIZATION));
            boolean authed = false;
            if (StrUtil.isNotEmpty(token)) {
                // 验证token
                if (jwtUtil.validateToken(token))
                    authed = true;
            }
            // Token 无效，直接返回响应
            if (!authed) {
                writeErrMsg(response);
                return false;
            }
        } catch (Exception e) {
            writeErrMsg(response);
            return false;
        }
        return true;
    }
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                @Nullable Exception ex) throws Exception {
        // 及时移除ThreadLocal数据，避免内存泄漏
        UserUtils.removeUser();
    }

    /**
     * 响应错误信息
     * @param response
     */
    private void writeErrMsg(HttpServletResponse response) {
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        response.setContentType(MediaType.APPLICATION_ATOM_XML_VALUE);
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        try (PrintWriter write = response.getWriter()) {
            String jsonResponse = JSONUtil.toJsonStr(Result.failed(ResultCode.ACCESS_UNAUTHORIZED));
            write.println(jsonResponse);
            write.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
